package org.itboys.mobile.service.mysql.mobile;

import org.apache.commons.lang3.StringUtils;
import org.itboys.admin.entity.lasted.SystemDictionary;
import org.itboys.admin.service.lasted.SystemDictionaryService;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.commons.utils.tools.LongUtil;
import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dao.TianJieGroupRecordMapper;
import org.itboys.mobile.dao.TianJieWalletProductMapper;
import org.itboys.mobile.dao.TianJieWalletRecordMapper;
import org.itboys.mobile.dao.TianJieWalletReleaseRecordMapper;
import org.itboys.mobile.dao.selling.TianJieSellingRewardMapper;
import org.itboys.mobile.entity.mongo.TianJieMember;
import org.itboys.mobile.entity.mysql.*;
import org.itboys.mobile.entity.mysql.selling.TianJieSellingReward;
import org.itboys.mobile.service.mongo.mobile.TianJieMobileAccountService;
import org.itboys.mobile.service.mongo.mobile.TianJieMobileMemberService;
import org.itboys.mysql.service.BaseMySqlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 作者：jiangxiong
 * 日期：2017年5月8日
 * 联系方式 ：empty90911@126.com
 * 描述：天街_消费卡_工具_service
 */
@Service
public class TianJieMobileWalletUtilService extends BaseMySqlService<TianJieWallet> {
    @Autowired
    private TianJieWalletRecordMapper walletRecordMapper;

    @Autowired
    private TianJieMobileMemberService memberService;

    @Autowired
    private TianJieMobileGroupService groupService;
    @Autowired
    private TianJieGroupRecordMapper groupRecordMapper ;

    @Autowired
    private TianJieSellingRewardMapper sellingRewardMapper;

    @Autowired
    private SystemDictionaryService dictionaryService;

    /**
     * 通过用户寻找消费卡钱包
     * @param memberId
     * @return
     */
    @Transactional
    public TianJieWallet findByMemberId(Long memberId ){
        Map<String,Object> param = new HashMap<String, Object>();
        param.put("memberId", memberId);
        TianJieWallet wallet=null;
        List<TianJieWallet> wallets=super.select(param);
        if(ListUtil.isNotNull(wallets)){
            wallet=wallets.get(0);
        }else {
            wallet=new TianJieWallet(memberId);
            super.insert(wallet);
            wallet=super.find(wallet.getId());
        }
        return wallet;
    }

    /**
     *2017年11月26日充值回掉或拨付回掉
     * @param chargeRecord ，预支付中生成的消费卡交易记录
     * @param remark 备注中包含支付编号
     * 业务逻辑
     * 1，结算业务分成。按本次充值金额。
     * 1.1，结算分成比例达到最高比例，结束分成
     * 1.2，结算分成达到最后一人，结束分成
     * 2,增加推荐链说有上级销售额度 （业绩）,更改等级
     *
     *
     *
     */
    @Transactional
    public void charge_callback(TianJieWalletRecord chargeRecord,String remark){
        //修改充值记录
        chargeRecord.setRemark(remark);
        chargeRecord.setStatus(SundayCommonConstants.YES);

        //2017年12月14日，充值记录一次性释放,充值记录要保留释放时间
        SystemDictionary releaseDayDic = dictionaryService.getDictionaryByKey2("releaseDay");
        Integer releaseDay=Integer.valueOf(releaseDayDic.getValue());
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.add(calendar.DAY_OF_YEAR, releaseDay);
        chargeRecord.setReleaseTime(calendar.getTime());

        walletRecordMapper.update(chargeRecord);
        //修改钱包主题
        TianJieWallet chargeWallet=findByMemberId(chargeRecord.getMemberId());
        chargeWallet.setTotalAmount(chargeWallet.getTotalAmount().add(chargeRecord.getAmount()));
        chargeWallet.setUnreleaseAmount(chargeWallet.getUnreleaseAmount().add(chargeRecord.getAmount()));
       super.update(chargeWallet);
        /********** ****************开始进行业绩分成***********************/
        logger.info("开始业绩分成");
        //第一步，获取充值记录和钱包主体

        /**
         *  1，结算业务分成。按本次充值金额。
         * 1.1，结算分成比例达到最高比例，结束分成
         * 1.2，结算分成达到最后一人，结束分成
         */
        TianJieMember member = memberService.getById(chargeRecord.getMemberId());
        //第二步，获取所有的提成比例配置信息。从底到高
        Map<String,Object> param = new HashMap<String,Object>();
        List<TianJieSellingReward> rewards = sellingRewardMapper.select(param);


        BigDecimal topScale=rewards.get(rewards.size()-1).getScale();



        //最高星级经理提出比例

        logger.info("----开始业绩分成--------------最高等级折扣--"+topScale);

        //推荐链ID集合。包含自己的ID
        logger.info("---------"+member.getFinanceTjPath());
        List<String> tjIdsStr = Arrays.asList(member.getFinanceTjPath().split("/"));
        List<Long> tjIds = new ArrayList<>();
        for(String tjIdStr:tjIdsStr){
            logger.info("------tjIdStr====="+String.valueOf(tjIdStr));
            tjIds.add(Long.valueOf(tjIdStr));
        }
        param.clear();
        //查询推荐链上的钱包（内含分成折扣）。按折扣比例，从小到大
        //重要，重要，重要，2017年12月10日，钱包的排序，要按推荐链上用户的顺序

        param.put("memberIds",tjIds);
       /* param.put("sort_name","scale");
        param.put("sort_order","ASC");*/
        List<TianJieWallet> tjWaltesNoSort =super.select(param);
        //  logger.info("-------tjMembers=="+tjMembers.size());
        //2017年12月10日，重要，重要，重要。重新按照用户的推荐顺序排序钱包用户
        List<TianJieWallet> tjWaltes =new ArrayList<>();
        for(int i=0;i<tjIds.size();i++){
            //倒着取推荐链上的ID。例如：2256/2275/2295/2296 ，新的用户的在后面
            long tjId = tjIds.get(tjIds.size()-i-1);
            for(TianJieWallet tjWalteNoSort:tjWaltesNoSort){
                if(tjId==tjWalteNoSort.getMemberId().longValue()){
                    tjWaltes.add(tjWalteNoSort);
                    break;
                }
            }
        }

        /**
         *  1，结算业务分成。按本次充值金额。
         * 1.1，结算分成比例达到最高比例，结束分成
         * 1.2，结算分成达到推荐链最后一人，结束分成
         * 1.3，2017年12月13日分成比例
         * 1.3,
         */
        BigDecimal zero = new BigDecimal("0");

        for(int i=0;i<tjWaltes.size();i++){
            //本次循环的钱包
            TianJieWallet thisTjWalte = tjWaltes.get(i);
            BigDecimal scale=new BigDecimal("0.00");;//提成比例
            BigDecimal scaleAmount=null;
           // boolean isSelfCharge=false;
            //如果钱包被冻结。不参与业绩分成
            if(thisTjWalte.getStatus()!=1){
                logger.info("----开始业绩分成----当前用户钱包被冻结--钱包ID"+thisTjWalte.getId());
                continue;
            }
            //2%,7%,14%,20
            //推荐链的的第一个人，就是自己
            /*if(i==0){
                scale=thisTjWalte.getScale();
                //logger.info("--本次用户ID="+thisTjWalte.getMemberId()+"--本次用户折扣"+thisTjWalte.getScale()+",上一级用户ID="+nextTjWalte.getMemberId()+"，"+"--本次用户折扣"+nextTjWalte.getScale());
            //推荐链的第二个及以后
            }else{
                //第一级往后就是，就是
                scale=thisTjWalte.getScale().subtract(tjWaltes.get(i-1).getScale());
            }*/
            //推荐链的的第一个人，就是自己。自己充值不提成
            if(i==0){
                scale=new BigDecimal("0");
                thisTjWalte.setScale(scale);
             //推荐链的第二个人及以后，是自己的上级
            }else{
                //2017年12月13日
                //1，充值人的直接上级，不需要比对比例差，直接就是上级的极差
                if(i==1){
                    scale=thisTjWalte.getScale();
                //2，充值人的直接上级以后的人，需要比对比例差
                }else{
                    scale=thisTjWalte.getScale().subtract(tjWaltes.get(i-1).getScale());
                }

            }
            scaleAmount=scale.multiply(chargeRecord.getAmount());


            //如果分成奖金小于0，有两种期刊
            //1，自己充值的
            //2，下级和自己是同样的折扣，
            if(scaleAmount.compareTo(zero)!=1){
                logger.info("----开始业绩分成----当前折扣差小于0--"+scale);
                thisTjWalte.setTotalAchievement(thisTjWalte.getTotalAchievement().add(chargeRecord.getAmount()));
            }else{
                logger.info("----开始业绩分成----当前折扣差大于于0--"+scale);
                thisTjWalte.setCashAmount(thisTjWalte.getCashAmount().add(scaleAmount));
                thisTjWalte.setTotalAchievement(thisTjWalte.getTotalAchievement().add(chargeRecord.getAmount()));
            }

            logger.info("----开始业绩分成-用户ID="+thisTjWalte.getMemberId()+"-分成折扣="+scale+"分成金额="+scaleAmount+"增加业绩="+chargeRecord.getAmount());
           super.update(thisTjWalte);
            if(scaleAmount.compareTo(zero)==1){
                TianJieWalletRecord walletRecord =new TianJieWalletRecord(thisTjWalte.getMemberId(),  thisTjWalte.getId(), SundayCommonConstants.wallet_record_type_achievement, "业绩分成", thisTjWalte.getCashAmount(),scaleAmount, SundayCommonConstants.YES);
               walletRecordMapper.insert(walletRecord);
            }

        }
      //  if(1==1)return;
        /**************************结束进行业绩分成***********************/
        /****************开始业绩叠加，更改用户等级，更改用户等级***********/
        /**
         * 1，所有下线推荐人的业绩。匹配用户等级
         * 2，所有一级推荐人的业绩。匹配星级经理
         */
        logger.info("开始业绩叠加，更改用户等级");
        param.clear();
        param.put("id in",tjIds);
        List<TianJieMember> tjMembers = memberService.list(param);
        //查询的用户信息包括用户的第一级推荐的会员
        List<String> tjFirstIdsStr=new ArrayList<>();
        List<Long> tjFirstIds=new ArrayList<>();
        for(TianJieMember tjMember:tjMembers){
            if(StringUtils.isNotEmpty(tjMember.getFinanceTjFirstPath())){
                tjFirstIdsStr.addAll(Arrays.asList(tjMember.getFinanceTjFirstPath().split("/")));
            }
        }
        if(ListUtil.isNull(tjFirstIdsStr))return;
        //重新查询用户
        for(String tjFirstIdStr:tjFirstIdsStr){
            tjFirstIds.add(Long.valueOf(tjFirstIdStr));
        }
        param.clear();
        //推荐链上的用户的第一级推荐人的钱包
        param.put("memberIds",tjFirstIds);
        List<TianJieWallet> tjFirstWallets = super.select(param);

        //
        for(TianJieWallet tjWalte:tjWaltes){
            logger.info("推荐链，钱包Id="+tjWalte.getId()+"-用户Id"+tjWalte.getMemberId());
        }
        for(TianJieWallet tjFirstWallet:tjFirstWallets){
            logger.info("推荐第一级链，钱包Id="+tjFirstWallet.getId()+"-用户Id"+tjFirstWallet.getMemberId());
        }
     //  if(1==1)return;


        //用户等级提成中中，最高提成比例
        BigDecimal topGradeScale=new BigDecimal("0");
        //等级折扣奖励
        List<TianJieSellingReward> gradeRewards = new ArrayList<>();
        //星级折扣奖励
        List<TianJieSellingReward> starRewards = new ArrayList<>();
        //星级折扣达标金额。要求维护的达标星级金额是一样
        BigDecimal starAchievement = null;
        for(TianJieSellingReward reward:rewards){
            if(reward.getType()==1){
                gradeRewards.add(reward);
                if(reward.getScale().compareTo(topGradeScale)==1){
                    topGradeScale=reward.getScale();
                }
            }else if(reward.getType()==2){
                starRewards.add(reward);
                starAchievement=reward.getAmount();
            }
        }
      //  logger.info("000000000000000000000000======"+rewards.size());

      //  return;
        //先把第一梯队的推荐人信息写入到钱包中
        for(TianJieWallet tjWalte:tjWaltes){
            for(TianJieMember tjMember:tjMembers){
                if(LongUtil.isNotZreo(tjWalte.getMemberId())&&
                        tjWalte.getMemberId().longValue()==tjMember.getId()){
                    tjWalte.setFinanceTjFirstPath(tjMember.getFinanceTjFirstPath());
                    break;
                }
            }
        }

        /*if(1==1){
            return;
        }*/
        /**
         * 判断逻辑
         * 1，用户已经是星级折扣。只判断星级折扣
         * 2，用户已经是等级折扣，先判断等级折扣，再判断星级折扣
         * 3，用户已经是最高提成比例，退出判断
         */
        //判断等级折扣
        for(TianJieWallet tjWalte:tjWaltes){
            //用户已经是最高提成比例，退出判断
            /*if(tjWalte.getScale().compareTo(topScale)!=-1){
                logger.info("开始业绩叠加，更改用户等级-已经是最高等级，用户ID="+tjWalte.getMemberId()+"当前折扣="+tjWalte.getScale());
                continue;
            }*/
            if(tjWalte.getStatus()!=1){
                logger.info("----开始业绩叠加----当前用户钱包被冻结--钱包ID"+tjWalte.getId());
                continue;
            }
            //新的折扣
            BigDecimal newScale= tjWalte.getScale();
            /*********************如果用户已经星级折扣，不再判断等级折扣***********/
            if(tjWalte.getScale().compareTo(topGradeScale)==1){
                logger.info("开始业绩叠加，更改用户等级-已是星级折扣，用户ID="+tjWalte.getMemberId());
                logger.info("当前最高星级折扣="+topScale+",当前星级最高业绩="+starAchievement);
                //如果该用户没有任何的第一推荐人
                if(StringUtils.isEmpty(tjWalte.getFinanceTjFirstPath())){
                    logger.info("开始业绩叠加，更改用户等级-已是星级折扣-没有一级团队，用户ID="+tjWalte.getMemberId());
                    continue;
                }

                //当前用户的第一级推荐的达标数量
                int starNumber=0;
                //当前用户的第一级推荐人钱包
                //获取达标的团队数量
                for(TianJieWallet tjFirstWallet:tjFirstWallets){
                    if(tjWalte.getFinanceTjFirstPath().contains(tjFirstWallet.getMemberId().toString())&&
                            tjFirstWallet.getTotalAchievement().compareTo(starAchievement)==1){
                        starNumber++;
                    }
                }

                //根据达标的团队数量，更新等级。算法1：按等于
                        /*for (TianJieSellingReward starReward : starRewards) {
                            if (starNumber == starReward.getNumber()) {
                                newScale = starReward.getScale();
                                break;
                            }
                        }*/
                //根据达标的团队数量，更新等级。算法2：按大于
                for (TianJieSellingReward starReward : starRewards) {
                    if (starNumber >= starReward.getNumber()) {
                        newScale = starReward.getScale();

                    }
                }
                logger.info("开始业绩叠加，更改用户等级-已是星级折扣，达标团队数量="+starNumber+"新折扣="+newScale+"用户ID="+tjWalte.getMemberId());

                /*********************用户已经是等级折扣，先判断等级折扣，再判断星级折扣***********/
                /** 假代码
                 * 新的等级折扣=算出结果。
                 *
                 * if(新的等级折扣>最高等级折扣){
                 *      判断星级折扣
                 * }
                 */
            }else {
                    logger.info("开始业绩叠加，更改用户等级-已是等级折扣，用户ID=" + tjWalte.getMemberId());

                    //算出新的等级折扣
                    for (TianJieSellingReward gradeReward : gradeRewards) {
                        //循环迭代出最大的折扣
                        if (tjWalte.getTotalAchievement().compareTo(gradeReward.getAmount()) == 1) {
                            newScale = gradeReward.getScale();
                        }
                    }
                    logger.info("开始业绩叠加，更改用户等级-已是等级折扣，新折扣=" + newScale + "用户ID=" + tjWalte.getMemberId());
                    //如果本次已经到达的最高的等级折扣，才判断星级折扣
                    //一级团队必须有值
                    if (newScale.compareTo(topGradeScale) != -1 && StringUtils.isNotEmpty(tjWalte.getFinanceTjFirstPath())) {
                        logger.info("开始业绩叠加，更改用户等级-达到最高等级折扣，进入星级折扣判断,用户ID=" + tjWalte.getMemberId() + "当前折扣=" + newScale);
                        int starNumber = 0;
                        //获取达标的团队数量
                        for (TianJieWallet tjFirstWallet : tjFirstWallets) {
                            if (tjWalte.getFinanceTjFirstPath().contains(tjFirstWallet.getMemberId().toString()) &&
                                    tjFirstWallet.getTotalAchievement().compareTo(starAchievement) == 1) {
                                starNumber++;
                            }
                        }
                        //根据达标的团队数量，更新等级。算法1：按等于
                        /*for (TianJieSellingReward starReward : starRewards) {
                            if (starNumber == starReward.getNumber()) {
                                newScale = starReward.getScale();
                                break;
                            }
                        }*/
                        //根据达标的团队数量，更新等级。算法2：按大于
                        for (TianJieSellingReward starReward : starRewards) {
                            if (starNumber >= starReward.getNumber()) {
                                newScale = starReward.getScale();
                            }
                        }
                        logger.info("开始业绩叠加，更改用户等级-达到最高等级折扣-进入星级折扣，达标团队数量="+starNumber+"新折扣="+newScale+"用户ID="+tjWalte.getMemberId());
                    }
                 }


            logger.info("业绩叠加结束。用户ID="+tjWalte.getMemberId()+",钱包ID="+tjWalte.getId()+",新折扣="+newScale+",旧折扣="+tjWalte.getScale());
            //更新提成比例
            if(newScale.compareTo(tjWalte.getScale())==1){
                tjWalte.setScale(newScale);
                super.update(tjWalte);
            }
        }
        logger.info("结束业绩叠加");
        /****************结束业绩叠加，更改用户等级***********/
        /***********-----开始创建释放计划-充值-4个月(16期)***/
        /***2017年12月10日，释放计划延迟创建--节省资源**/
       // BigDecimal chargeAmount
        /*Calendar calendar = Calendar.getInstance();
        Date now = new Date();
        now.setHours(0);
        now.setMinutes(0);
        now.setSeconds(0);
        BigDecimal releaseAmount = chargeRecord.getAmount().divide(new BigDecimal("16"),2,BigDecimal.ROUND_HALF_UP);
        for(int i=0;i<16;i++) {
            calendar.setTime(now);
            calendar.add(calendar.WEEK_OF_YEAR, i + 1);
            releaseRecordMapper.insert(new TianJieWalletReleaseRecord(
                    chargeRecord.getMemberId(),chargeRecord.getWalletId(), chargeRecord.getId(),
                    "未释放",
                    calendar.getTime(),
                    releaseAmount));
        }*/

        /***********-----结束创建释放计划-充值***/

    }

    /**
     *2017年11月26日拨付回掉
     * @param captainId ，队长
     * @param partnerId ，队员ID
     * @param presentAmount 拨付金额
     * 业务逻辑
     * 1，结算业务分成。按本次充值金额。
     * 1.1，结算分成比例达到最高比例，结束分成
     * 1.2，结算分成达到最后一人，结束分成
     * 2,增加推荐链说有上级销售额度 （业绩）,更改等级
     *
     *
     */
    @Transactional
    public void present(long captainId,long partnerId,BigDecimal presentAmount) {
        //校验是否是队长
        TianJieMember captain = memberService.getById(captainId);
        if (captain.getFinanceIsCaptain() != SundayCommonConstants.YES) {
            throw new ErrorException("您不是队长，无法拨付");
        }

        //获取团队可用金额
        TianJieGroup group = groupService.find(captain.getFinanceGroupId());
        if (presentAmount.compareTo(group.getPresentAmount()) == 1) {
            throw new ErrorException("团队可用拨付金额不足，请重试");
        }
        //扣减团队的可用拨付金额
        group.setPresentAmount(group.getPresentAmount().subtract(presentAmount));
        groupService.update(group);
        //生成团队拨付记录
        TianJieMember partner = memberService.getById(partnerId);
        groupRecordMapper.insert(new TianJieGroupRecord(group.getId(), partnerId, partner.getNickName(), presentAmount, SundayCommonConstants.group_record_type_captain));
        //更改队员的钱包和钱包记录
        TianJieWallet partnerWallet = findByMemberId(partnerId);
        partnerWallet.setTotalAmount(partnerWallet.getTotalAmount().add(presentAmount));
        partnerWallet.setUnreleaseAmount(partnerWallet.getUnreleaseAmount().add(presentAmount));
        super.update(partnerWallet);

        TianJieWalletRecord partnerWalletRecord = new TianJieWalletRecord(partnerId, partnerWallet.getId(), SundayCommonConstants.wallet_record_type_present, "队长拨付", partnerWallet.getUnreleaseAmount(), presentAmount, SundayCommonConstants.YES);
        walletRecordMapper.insert(partnerWalletRecord);
    }
}
